package com.zHan.system.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zHan.model.dto.AssginPostDto;
import com.zHan.model.dto.SysPostQueryDto;
import com.zHan.model.system.SysPost;
import com.zHan.model.system.SysUser;
import com.zHan.model.system.SysUserPost;
import com.zHan.system.exception.MyException;
import com.zHan.system.mapper.SysPostMapper;
import com.zHan.system.mapper.SysUserMapper;
import com.zHan.system.mapper.SysUserPostMapper;
import com.zHan.system.service.ISysPostService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * <p>
 * 岗位信息表 服务实现类
 * </p>
 *
 * @author zHan
 * @since 2023-06-24
 */
@Service
@Transactional
public class SysPostServiceImpl extends ServiceImpl<SysPostMapper, SysPost> implements ISysPostService {
    @Autowired
    private SysPostMapper sysPostMapper;

    @Autowired
    private SysUserPostMapper userPostMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    /**
     * 分页条件查询
     *
     * @param page
     * @param pageSize
     * @param postQueryVo
     * @return
     */
    @Override
    public Page<SysPost> selectPageQuery(Long page, Long pageSize, SysPostQueryDto postQueryVo) {
        // 创建Page对象
        Page<SysPost> pageInfo = new Page<>(page, pageSize);
        // 条件查询
        LambdaQueryWrapper<SysPost> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        //准备参数
        String postCode = postQueryVo.getPostCode();
        String name = postQueryVo.getName();
        Integer status = postQueryVo.getStatus();

        if (!StringUtils.isEmpty(postCode)) {
            lambdaQueryWrapper.like(SysPost::getPostCode, postCode);
        }

        if (!StringUtils.isEmpty(name)) {
            lambdaQueryWrapper.like(SysPost::getName, name);
        }

        if (!StringUtils.isEmpty(status)) {
            lambdaQueryWrapper.like(SysPost::getStatus, status);
        }

        //执行方法
        this.page(pageInfo, lambdaQueryWrapper);
        return pageInfo;
    }

    /**
     * 更改用户状态
     *
     * @param id
     * @param status
     * @return
     */
    @Override
    public boolean updateStatus(Long id, Integer status) {
        SysPost user = sysPostMapper.selectById(id);
        user.setStatus(status);
        return this.updateById(user);
    }

    /**
     * 给用户分配岗位
     *
     * @param assginPostDto
     * @return
     */
    @Override
    public boolean assignPostToUser(AssginPostDto assginPostDto) {
        // 获取对应的id
        String userId = assginPostDto.getUserId();
        String postId = assginPostDto.getPostId();

        // 查询用户，并修改
        SysUser sysUser = sysUserMapper.selectById(userId);
        sysUser.setPostId(postId);
        sysUser.setUpdateTime(new Date());
        sysUserMapper.updateById(sysUser);

        // 根据userId删除已分配的岗位
        LambdaQueryWrapper<SysUserPost> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysUserPost::getUserId, assginPostDto.getUserId());
        userPostMapper.delete(lambdaQueryWrapper);

        // 获取岗位id，添加到用户岗位关系表
        SysUserPost sysUserPost = new SysUserPost();
        sysUserPost.setUserId(assginPostDto.getUserId());
        sysUserPost.setPostId(assginPostDto.getPostId());
        userPostMapper.insert(sysUserPost);

        return true;
    }

    /**
     * 获取用户的岗位数据
     *
     * @param userId
     * @return
     */
    @Override
    public Map<String, Object> selectPostsByUserId(String userId) {
        // 获取所有岗位集合
        List<SysPost> posts = sysPostMapper.selectList(null);

        // 获取userId对应的岗位
        LambdaQueryWrapper<SysUserPost> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysUserPost::getUserId, userId);
        List<SysUserPost> userPostList = userPostMapper.selectList(lambdaQueryWrapper);

        // 获得所有的岗位id
        List<String> postIds = new ArrayList<>();
        for (SysUserPost userPost : userPostList) {
            postIds.add(userPost.getPostId());
        }

        // 返回map集合
        Map<String, Object> map = new HashMap<>();
        map.put("allPosts", posts);
        map.put("userPostId", postIds);

        return map;
    }

    /**
     * 删除岗位
     *
     * @param id
     * @return
     */
    @Override
    public boolean removePostById(Long id) {
        //查询岗位信息，确定是否可以删除
        LambdaQueryWrapper<SysPost> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper
                .eq(SysPost::getStatus, 1)
                .eq(SysPost::getId, id);
        //不能删除，抛出业务异常
        if (this.getOne(lambdaQueryWrapper) != null) {
            throw new MyException(201, "岗位在启用状态，不能删除");
        }

        try {
            //先删除岗位表中的信息
            this.removeById(id);
            //再删除其他表中的数据
            userPostMapper.delete(Wrappers.<SysUserPost>lambdaQuery()
                    .eq(SysUserPost::getPostId, id));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        return true;
    }

    /**
     * 批量删除岗位
     *
     * @param idList
     * @return
     */
    @Override
    public boolean removePostByIds(List<Long> idList) {
        //查询岗位信息，确定是否可以删除
        LambdaQueryWrapper<SysPost> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper
                .eq(SysPost::getStatus, 1)
                .in(SysPost::getId, idList);
        //不能删除，抛出业务异常
        if (this.count(lambdaQueryWrapper) > 0) {
            throw new MyException(201, "有岗位在启用状态，不能删除");
        }

        try {
            //先删除岗位表中的信息
            this.removeByIds(idList);
            //再删除其他表中的数据
            userPostMapper.delete(Wrappers.<SysUserPost>lambdaQuery()
                    .in(SysUserPost::getPostId, idList));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        return true;
    }
}
